/* 
 * thread_switch.S: Context switch between user-level threads
 *
 * Context switch routine for xv6 user-level threads
 * Save current thread's registers and restore next thread's registers
 */

.globl thread_switch
thread_switch:
  # Save current thread's registers
  pushal               # Push all registers onto the stack

  # Save current ESP to current_thread->sp
  movl current_thread, %eax
  movl %esp, (%eax)   # current_thread->sp = %esp

  # Load next thread's ESP from next_thread->sp
  movl next_thread, %eax
  movl %eax, current_thread  # current_thread = next_thread
  movl (%eax), %esp   # %esp = next_thread->sp

  # Restore next thread's registers
  popal                # Pop all registers from the stack

  ret                  # Return to the next thread's execution point